package bibliotheque.transaction;

import bibliotheque.document.Document;
import bibliotheque.document.DocumentSummary;
import bibliotheque.server.Server;
import java.util.ArrayList;
import java.util.concurrent.Semaphore;

public class Transaction {
    
    public enum State {RESOLVING, RESOLVED, SELECTING, SELECTED};
    
    private State state;
    private TransactionId id;
    private ArrayList<String> filter;
    private Server.SelectionType type;
    private boolean resolv;
    private int resolv_nb;
    private ArrayList<Document> documents;
    private ArrayList<DocumentSummary> summaries;
    private Semaphore select_mutex;
    
    public Transaction(TransactionId id,ArrayList<String> filter, Server.SelectionType type) {
        this.state = State.RESOLVING;
        this.id = id;
        this.filter = filter;
        this.type = type;
        this.resolv = true;
        this.resolv_nb = 0;
        this.documents = new ArrayList<Document>();
        this.summaries = new ArrayList<DocumentSummary>();
        this.select_mutex = new Semaphore(1);
        
    }
    
    public TransactionId GetId() {
        return(this.id);
    }
    
    public ArrayList<String> GetFiltre() {
        return(this.filter);
    }
    
    public Server.SelectionType GetType() {
        return(this.type);
    }
    
    public State GetState() {
        return(this.state);
    }
    
    public void SetState(State state) {
        this.state = state;
    }
    
    public boolean GetResolv() {
        return(this.resolv);
    }
    
    public void SetResolv(boolean resolv) {
        this.resolv = resolv;
    }
    
    public int GetResolvNb() {
        return(this.resolv_nb);
    }
    
    public void SetResolvNb(int resolv_nb) {
        this.resolv_nb = resolv_nb;
    }
    
    public ArrayList<Document> GetDocuments() {
        return(this.documents);
    }
    
    public ArrayList<DocumentSummary> GetSummaries() {
        if(this.state == State.SELECTING) {
            for(int i=0;i<this.documents.size();i++) {
                this.summaries.add(this.documents.get(i).GetDocSummary());
            }
            this.state = State.SELECTED;
        }
        return(this.summaries);
    }
    
    public void AddSummaries(ArrayList<DocumentSummary> summaries) {
        this.summaries.addAll(summaries);
    }
    
    public void AddDocument(Document doc) {
        this.documents.add(doc);
    }
    
    public void RemoveDocument(Document doc) {
        this.documents.remove(doc);
    }
    
    public void AcquireSelectMutex() {
        this.select_mutex.acquireUninterruptibly();
    }
    
    public void ReleaseSelectMutex() {
        this.select_mutex.release();
    }
    
    public boolean ResolvPrior(Transaction transaction) {
        if(transaction.state == State.RESOLVED) return(false);
        if(transaction.state == State.SELECTING) return(true);
        if(transaction.state == State.SELECTED) return(true);
        boolean prior = true;
        ArrayList<String> filtre2 = transaction.GetFiltre();
        for(int i=0;prior && i<this.filter.size();i++) {
            prior = !filtre2.contains(this.filter.get(i));
        }
        
        prior |= this.GetResolvNb() > transaction.GetResolvNb();
        prior |= this.GetResolvNb() == transaction.GetResolvNb() && this.GetId().compareTo(transaction.GetId()) > 0;
        
        return(prior);
    }
}
